using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EventSystem
{
    private readonly Dictionary<GameEventType, Delegate> _actionEvents = new Dictionary<GameEventType, Delegate>();

    // 带返回值事件字典
    private readonly Dictionary<GameEventType, Delegate> _funcEvents = new Dictionary<GameEventType, Delegate>();

    #region 无返回值事件注册与触发 (Action系列)
    // 无参数
    public void RegisterEvent(GameEventType eventType, Action callback)
    {
        if (_actionEvents.TryGetValue(eventType, out var existing))
        {
            _actionEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _actionEvents[eventType] = callback;
        }
    }

    // 1个参数
    public void RegisterEvent<T>(GameEventType eventType, Action<T> callback)
    {
        if (_actionEvents.TryGetValue(eventType, out var existing))
        {
            _actionEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _actionEvents[eventType] = callback;
        }
    }

    // 2个参数
    public void RegisterEvent<T1, T2>(GameEventType eventType, Action<T1, T2> callback)
    {
        if (_actionEvents.TryGetValue(eventType, out var existing))
        {
            _actionEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _actionEvents[eventType] = callback;
        }
    }

    // 3个参数
    public void RegisterEvent<T1, T2, T3>(GameEventType eventType, Action<T1, T2, T3> callback)
    {
        if (_actionEvents.TryGetValue(eventType, out var existing))
        {
            _actionEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _actionEvents[eventType] = callback;
        }
    }

    // 4个参数
    public void RegisterEvent<T1, T2, T3, T4>(GameEventType eventType, Action<T1, T2, T3, T4> callback)
    {
        if (_actionEvents.TryGetValue(eventType, out var existing))
        {
            _actionEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _actionEvents[eventType] = callback;
        }
    }

    // 无参数触发
    public void TriggerEvent(GameEventType eventType)
    {
        if (!_actionEvents.TryGetValue(eventType, out var callback)) return;

        if (callback is Action action)
        {
            action?.Invoke();
        }
        else
        {
            Debug.LogError($"事件 {eventType} 类型不匹配，期望无参数Action");
        }
    }

    // 1个参数触发
    public void TriggerEvent<T>(GameEventType eventType, T arg)
    {
        if (!_actionEvents.TryGetValue(eventType, out var callback)) return;

        if (callback is Action<T> action)
        {
            action?.Invoke(arg);
        }
        else
        {
            Debug.LogError($"事件 {eventType} 类型不匹配，期望 Action<{typeof(T)}>");
        }
    }

    // 2个参数触发
    public void TriggerEvent<T1, T2>(GameEventType eventType, T1 arg1, T2 arg2)
    {
        if (!_actionEvents.TryGetValue(eventType, out var callback)) return;

        if (callback is Action<T1, T2> action)
        {
            action?.Invoke(arg1, arg2);
        }
        else
        {
            Debug.LogError($"事件 {eventType} 类型不匹配，期望 Action<{typeof(T1)}, {typeof(T2)}>");
        }
    }

    // 3个参数触发
    public void TriggerEvent<T1, T2, T3>(GameEventType eventType, T1 arg1, T2 arg2, T3 arg3)
    {
        if (!_actionEvents.TryGetValue(eventType, out var callback)) return;

        if (callback is Action<T1, T2, T3> action)
        {
            action?.Invoke(arg1, arg2, arg3);
        }
        else
        {
            Debug.LogError($"事件 {eventType} 类型不匹配，期望 Action<{typeof(T1)}, {typeof(T2)}, {typeof(T3)}>");
        }
    }

    // 4个参数触发
    public void TriggerEvent<T1, T2, T3, T4>(GameEventType eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
    {
        if (!_actionEvents.TryGetValue(eventType, out var callback)) return;

        if (callback is Action<T1, T2, T3, T4> action)
        {
            action?.Invoke(arg1, arg2, arg3, arg4);
        }
        else
        {
            Debug.LogError($"事件 {eventType} 类型不匹配，期望 Action<{typeof(T1)}, {typeof(T2)}, {typeof(T3)}, {typeof(T4)}>");
        }
    }
    #endregion

    #region 带返回值事件注册与触发 (Func系列)
    // 无参数带返回值
    public void RegisterEvent<TResult>(GameEventType eventType, Func<TResult> callback)
    {
        if (_funcEvents.TryGetValue(eventType, out var existing))
        {
            _funcEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _funcEvents[eventType] = callback;
        }
    }

    // 1个参数带返回值
    public void RegisterEvent<T, TResult>(GameEventType eventType, Func<T, TResult> callback)
    {
        if (_funcEvents.TryGetValue(eventType, out var existing))
        {
            _funcEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _funcEvents[eventType] = callback;
        }
    }

    // 2个参数带返回值
    public void RegisterEvent<T1, T2, TResult>(GameEventType eventType, Func<T1, T2, TResult> callback)
    {
        if (_funcEvents.TryGetValue(eventType, out var existing))
        {
            _funcEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _funcEvents[eventType] = callback;
        }
    }

    // 3个参数带返回值
    public void RegisterEvent<T1, T2, T3, TResult>(GameEventType eventType, Func<T1, T2, T3, TResult> callback)
    {
        if (_funcEvents.TryGetValue(eventType, out var existing))
        {
            _funcEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _funcEvents[eventType] = callback;
        }
    }

    // 4个参数带返回值
    public void RegisterEvent<T1, T2, T3, T4, TResult>(GameEventType eventType, Func<T1, T2, T3, T4, TResult> callback)
    {
        if (_funcEvents.TryGetValue(eventType, out var existing))
        {
            _funcEvents[eventType] = Delegate.Combine(existing, callback);
        }
        else
        {
            _funcEvents[eventType] = callback;
        }
    }

    // 无参数带返回值触发
    public TResult TriggerFuncEvent<TResult>(GameEventType eventType)
    {
        if (!_funcEvents.TryGetValue(eventType, out var callback)) return default;

        if (callback is Func<TResult> func)
        {
            return func != null ? func.Invoke() : default;
        }

        Debug.LogError($"事件 {eventType} 类型不匹配，期望 Func<{typeof(TResult)}>");
        return default;
    }

    // 1个参数带返回值触发
    public TResult TriggerFuncEvent<T, TResult>(GameEventType eventType, T arg)
    {
        if (!_funcEvents.TryGetValue(eventType, out var callback)) return default;

        if (callback is Func<T, TResult> func)
        {
            return func != null ? func.Invoke(arg) : default;
        }

        Debug.LogError($"事件 {eventType} 类型不匹配，期望 Func<{typeof(T)}, {typeof(TResult)}>");
        return default;
    }

    // 2个参数带返回值触发
    public TResult TriggerFuncEvent<T1, T2, TResult>(GameEventType eventType, T1 arg1, T2 arg2)
    {
        if (!_funcEvents.TryGetValue(eventType, out var callback)) return default;

        if (callback is Func<T1, T2, TResult> func)
        {
            return func != null ? func.Invoke(arg1, arg2) : default;
        }

        Debug.LogError($"事件 {eventType} 类型不匹配，期望 Func<{typeof(T1)}, {typeof(T2)}, {typeof(TResult)}>");
        return default;
    }

    // 3个参数带返回值触发
    public TResult TriggerFuncEvent<T1, T2, T3, TResult>(GameEventType eventType, T1 arg1, T2 arg2, T3 arg3)
    {
        if (!_funcEvents.TryGetValue(eventType, out var callback)) return default;

        if (callback is Func<T1, T2, T3, TResult> func)
        {
            return func != null ? func.Invoke(arg1, arg2, arg3) : default;
        }

        Debug.LogError($"事件 {eventType} 类型不匹配，期望 Func<{typeof(T1)}, {typeof(T2)}, {typeof(T3)}, {typeof(TResult)}>");
        return default;
    }

    // 4个参数带返回值触发
    public TResult TriggerFuncEvent<T1, T2, T3, T4, TResult>(GameEventType eventType, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
    {
        if (!_funcEvents.TryGetValue(eventType, out var callback)) return default;

        if (callback is Func<T1, T2, T3, T4, TResult> func)
        {
            return func != null ? func.Invoke(arg1, arg2, arg3, arg4) : default;
        }

        Debug.LogError($"事件 {eventType} 类型不匹配，期望 Func<{typeof(T1)}, {typeof(T2)}, {typeof(T3)}, {typeof(T4)}, {typeof(TResult)}>");
        return default;
    }
    #endregion

    #region 事件注销
    // 无参数无返回值注销
    public void UnregisterEvent(GameEventType eventType, Action callback)
    {
        if (!_actionEvents.TryGetValue(eventType, out var existing)) return;

        var newDelegate = Delegate.Remove(existing, callback);
        if (newDelegate == null)
        {
            _actionEvents.Remove(eventType);
        }
        else
        {
            _actionEvents[eventType] = newDelegate;
        }
    }

    // 1个参数无返回值注销
    public void UnregisterEvent<T>(GameEventType eventType, Action<T> callback)
    {
        if (!_actionEvents.TryGetValue(eventType, out var existing)) return;

        var newDelegate = Delegate.Remove(existing, callback);
        if (newDelegate == null)
        {
            _actionEvents.Remove(eventType);
        }
        else
        {
            _actionEvents[eventType] = newDelegate;
        }
    }

    // 无参数带返回值注销
    public void UnregisterEvent<TResult>(GameEventType eventType, Func<TResult> callback)
    {
        if (!_funcEvents.TryGetValue(eventType, out var existing)) return;

        var newDelegate = Delegate.Remove(existing, callback);
        if (newDelegate == null)
        {
            _funcEvents.Remove(eventType);
        }
        else
        {
            _funcEvents[eventType] = newDelegate;
        }
    }

    // 1个参数带返回值注销
    public void UnregisterEvent<T, TResult>(GameEventType eventType, Func<T, TResult> callback)
    {
        if (!_funcEvents.TryGetValue(eventType, out var existing)) return;

        var newDelegate = Delegate.Remove(existing, callback);
        if (newDelegate == null)
        {
            _funcEvents.Remove(eventType);
        }
        else
        {
            _funcEvents[eventType] = newDelegate;
        }
    }
    // 其他参数数量的注销方法类似，根据需要添加...
    #endregion

    /// <summary>
    /// 清除所有事件监听
    /// </summary>
    public void ClearAllEvents()
    {
        _actionEvents.Clear();
        _funcEvents.Clear();
    }

    private void OnDestroy()
    {
        ClearAllEvents();
    }
}

